Skip to content

Add write-data-frame-region for zero-copy DATA frame sending#7

Closed
jcmallery wants to merge 1 commit into
zellerin:masterfrom
jcmallery:write-data-frame-region
Closed

Add write-data-frame-region for zero-copy DATA frame sending#7
jcmallery wants to merge 1 commit into
zellerin:masterfrom
jcmallery:write-data-frame-region

Conversation

@jcmallery

Copy link
Copy Markdown

Summary

  • Adds write-data-frame-region to core/frames/data.lisp
  • Like write-data-frame but accepts source buffer + offset + length
  • Copies only the specified region into the frame buffer, avoiding an intermediate subseq allocation

Motivation

When sending large HTTP/2 responses as multiple DATA frames (e.g., splitting a 64KB buffer into four 16KB frames), each frame currently requires:

  1. (subseq buffer start (+ start 16384)) — 16KB allocation + copy
  2. write-frame's replace into the frame buffer — 16KB copy

With write-data-frame-region, only step 2 remains (single copy directly from the source region).

This eliminates ~64 MB/s of nursery consing at peak throughput in CL-HTTP's HTTP/2 server.

Testing

Tested extensively in CL-HTTP on SBCL:

  • 75 MB/s throughput for 10MB files over HTTP/2+TLS
  • 1000 concurrent requests at 64-way concurrency with zero failures
  • Handles padding and end-stream correctly

API

(write-data-frame-region stream source source-offset payload-length
                         &key padded end-stream)

Thank you for the excellent http2 library!

🤖 Generated with Claude Code

write-data-frame-region accepts a source buffer with offset and length
instead of a whole octet vector.  This eliminates an intermediate subseq
allocation when sending large responses as multiple DATA frames.

Use case: when splitting a 64KB response buffer into four 16KB DATA
frames, each frame previously required:
  1. (subseq buffer start (+ start 16384)) — 16KB alloc + copy
  2. write-frame's replace into frame buffer — 16KB copy

With write-data-frame-region, only step 2 remains (single copy from
the source region directly into the frame buffer).

Tested in CL-HTTP's HTTP/2 server on SBCL: 75 MB/s throughput for
10MB files, 1000 concurrent requests with zero failures.
@zellerin

zellerin commented Apr 4, 2026

Copy link
Copy Markdown
Owner

Thanks for the discussion. The function is now in v2.0.5 implemented a slightly different way.

@zellerin zellerin closed this Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants